
/**
 * @author klaoye(K老叶)
 * @email klaoye@163.com
 * @license Apache 2.0
*/
import com.mpatric.mp3agic.*;
import javazoom.jl.decoder.Bitstream;
import javazoom.jl.decoder.JavaLayerException;
import javazoom.jl.player.Player;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionListener;
import java.awt.event.ItemListener;
import java.io.*;
import java.util.Objects;

public class UI {
    private boolean isPlay = false;// 是否在播放
    private boolean isAutoPlay = true;// 是否自动播放

    private final JFrame mainFrame;// 主窗口
    private final FileOperate fileOperate;// 文件操作类
    private File[] FileList;// 文件列表
    private String FilePath;
    private File music;// 目标文件名
    private final ImageIcon START_ICON = new ImageIcon(getClass().getResource("res/images/startICON.png"));
    private final ImageIcon DEFAULT_ICON = new ImageIcon(getClass().getResource("res/images/music.png"));
    private final ImageIcon STOP_ICON = new ImageIcon(getClass().getResource("res/images/stopICON.png"));
    private final JComboBox<String> FileComboBox/* 文件选择框 */, TypeCombobox/* 文件类型框 */;
    private final JCheckBox AutoPlayCheckBox;// 自动播放选框
    private final JLabel timeLength/* 时间总长 */, playtime/* 当前播放时间 */, musicImage/* 专辑图片 */, musicMessage/* 歌曲信息 */;
    private final JButton playButton;// 播放、停止键

    private Thread AutoPlayOperaThread;// 自动播放线程
    private Thread thread;// 音乐播放线程
    private Thread timer;

    public UI() {

        JPanel ComboBoxPanel = new JPanel(new GridLayout(1, 3, 5, 5));// 下拉框面板
        JPanel LabelPanel = new JPanel(new GridLayout(1, 2, 5, 5));// 标签面板

        mainFrame = new JFrame("音乐播放器");
        // 窗口容器
        Container container = new Container();
        TypeCombobox = new JComboBox<>();
        FileComboBox = new JComboBox<>();
        playButton = new JButton(START_ICON);
        timeLength = new JLabel("总时长：0:0");
        playtime = new JLabel("已播放：0:0");
        AutoPlayCheckBox = new JCheckBox("自动播放下一首");
        musicImage = new JLabel();
        musicMessage = new JLabel("music");
        fileOperate = new FileOperate(mainFrame);

        FileList = fileOperate.fileFilter("mp3");
        if (FileList.length == 0) {
            System.out.println("此文件夹没有可播放文件！");
            System.exit(0);
        }

        music = FileList[0];
        thread = new Thread(PlayRunnable(music));

        mainFrame.setBounds(50, 50, 800, 610);
        container.setBounds(50, 50, 800, 610);

        mainFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        mainFrame.setResizable(true);
        mainFrame.setIconImage(DEFAULT_ICON.getImage());
        container.setLayout(new BorderLayout());

        TypeCombobox.addItem("mp3");
        // TypeCombobox.addItem("wav");
        TypeCombobox.addItemListener(e -> {/* 更换文件列表 */
            FileComboBox.removeAllItems();
            FileList = null;
            FileList = fileOperate.fileFilter(e.getItem().toString());
            for (File file : FileList)
                FileComboBox.addItem(file.getName());
        });

        for (File file : FileList)
            FileComboBox.addItem(file.getName());
        FilePath = FileList[0].getParent() + '\\';
        System.out.println(FilePath);
        FileComboBox.addItemListener(FileComboboxListener());

        playButton.setContentAreaFilled(false);
        playButton.addActionListener(PlayButtonListener());

        AutoPlayCheckBox.setSelected(true);
        AutoPlayCheckBox.addChangeListener(changeEvent -> {
            if (AutoPlayCheckBox.isSelected()) {
                isAutoPlay = true;
                AutoPlayOperaThread = null;
                AutoPlayOperaThread = new Thread(AutoPlayOperate());
                System.out.println("Auto Play Operate Thread is start.");
            } else {
                AutoPlayOperaThread = null;
                isAutoPlay = false;
                System.out.println("Auto Play Operate Thread is stop.");
            }

        });

        AutoPlayCheckBox.setFont(Font.getFont("楷体"));
        FileComboBox.setFont(Font.getFont("楷体"));
        musicMessage.setFont(Font.getFont("SimSun"));
        playtime.setFont(Font.getFont("KaiTi"));
        timeLength.setFont(Font.getFont("KaiTi"));

        ComboBoxPanel.add(FileComboBox);
        ComboBoxPanel.add(TypeCombobox);
        ComboBoxPanel.add(AutoPlayCheckBox);
        LabelPanel.add(playtime);
        LabelPanel.add(timeLength);

        container.add(playButton, BorderLayout.EAST);
        container.add(ComboBoxPanel, BorderLayout.NORTH);
        container.add(LabelPanel, BorderLayout.SOUTH);
        container.add(musicImage, BorderLayout.CENTER);
        container.add(musicMessage, BorderLayout.WEST);

        AutoPlayOperaThread = new Thread(AutoPlayOperate());
        // AutoPlayOperaThread.start();
        mainFrame.add(container);
        mainFrame.setVisible(true);

    }

    // 播放按钮监听器
    private ActionListener PlayButtonListener() {
        return event -> {
            if (!isPlay) {
                if (thread != null)
                    thread.start();
                playButton.setIcon(STOP_ICON);
                FileComboBox.setEnabled(false);
                TypeCombobox.setEnabled(false);
                isPlay = true;
                if (isAutoPlay) {
                    AutoPlayOperaThread.start();
                    try {
                        Runtime.getRuntime().exec("cls");
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    System.out.println("Auto Play Operate Thread is start.");
                }
            } else {
                thread.stop();
                playButton.setIcon(START_ICON);
                FileComboBox.setEnabled(true);
                TypeCombobox.setEnabled(true);
                isPlay = false;
                thread = null;
                System.gc();
                thread = new Thread(PlayRunnable(music));
                AutoPlayCheckBox.setSelected(false);
                timer.stop();
                playtime.setText("已播放：0:0");
                if (isAutoPlay) {
                    AutoPlayOperaThread.stop();
                    try {
                        Runtime.getRuntime().exec("cls");
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    System.out.println("Auto Play Operate Thread is stop.");
                    AutoPlayOperaThread = null;
                    AutoPlayOperaThread = new Thread(AutoPlayOperate());
                }
            }

        };
    }

    // 自动播放操作
    private Runnable AutoPlayOperate() {
        return () -> {
            while (true) {

                if (isAutoPlay) {
                    if (!thread.isAlive()) {
                        playButton.setIcon(START_ICON);
                        FileComboBox.setEnabled(true);

                        if (FileComboBox.getSelectedIndex() >= FileComboBox.getItemCount() - 1) {
                            FileComboBox.setSelectedIndex(0);
                            music = new File(FilePath + FileComboBox.getSelectedItem());
                            thread = null;
                            thread = new Thread(PlayRunnable(music));
                            isPlay = false;
                            AutoPlayCheckBox.setSelected(false);
                            TypeCombobox.setEnabled(true);
                            break;
                        }

                        System.out.println("AutoPlay:" + FileComboBox.getSelectedItem());
                        FileComboBox.setSelectedIndex(FileComboBox.getSelectedIndex() + 1);
                        System.out.println("AutoPlay:" + FileComboBox.getSelectedItem());
                        FileComboBox.setEnabled(false);
                        thread = null;
                        System.gc();

                        music = new File(FilePath + FileComboBox.getSelectedItem());
                        // System.out.println("AutoPlay:" + music);
                        thread = new Thread(PlayRunnable(music));
                        thread.start();
                        isPlay = true;
                        playButton.setIcon(STOP_ICON);
                    }
                }
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };

    }

    // 文件选择器
    private ItemListener FileComboboxListener() {
        return e -> {
            music = new File(FilePath + e.getItem());
            System.out.println(e.getItem().toString());
            thread = null;
            // System.gc();
            thread = new Thread(PlayRunnable(music));
        };
    }

    // 播放操作
    private Runnable PlayRunnable(File music) {
        return () -> {
            timer = timer();
            int FullTime;
            try {
                FileInputStream FIS = new FileInputStream(music);
                BufferedInputStream BIS = new BufferedInputStream(FIS);
                Player player = new Player(BIS);

                mainFrame.setTitle("音乐播放器——" + music.getName());

                /* 总时长获取 */
                Bitstream BS = new Bitstream(FIS);
                FullTime = (int) BS.readFrame().total_ms(FIS.available());
                FullTime /= 1000;
                timeLength.setText("总时长：" + FullTime / 60 + ':' + FullTime % 60);

                /* 播放并计时 */
                timer.start();
                getMp3Tag(music.getPath());
                player.play();
                timer.stop();
                playtime.setText("已播放：0:0");

                mainFrame.setTitle("音乐播放器");

                FIS.close();
                BIS.close();
                timer = null;
                timer = timer();
            } catch (JavaLayerException | IOException | InvalidDataException | UnsupportedTagException e) {
                e.printStackTrace();
            }
        };
    }

    // 计时器线程
    private Thread timer() {
        return new Thread() {
            @Override
            public void run() {
                int m = 0, s = 0, time = 0;
                super.run();
                while (true) {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    time++;
                    m = time / 60;
                    s = time % 60;
                    playtime.setText("已播放：" + m + ':' + s);
                }
            }
        };
    }

    // 歌曲信息获取
    private void getMp3Tag(String filePath) throws InvalidDataException, IOException, UnsupportedTagException {

        Mp3File file = new Mp3File(filePath);
        String message;
        if (file.hasId3v2Tag()) {
            ID3v2 tag = file.getId3v2Tag();
            if (tag.getAlbumImage() != null) {// MP3文件是否有图片
                ImageIcon icon = new ImageIcon(tag.getAlbumImage());
                musicImage.setIcon(icon);
                mainFrame.setIconImage(icon.getImage());
            } else {
                musicImage.setIcon(DEFAULT_ICON);
                mainFrame.setIconImage(DEFAULT_ICON.getImage());
            }

            message = "<html><body>" +
                    "歌曲名：" + tag.getTitle() + "<br>" +
                    "演唱者：" + tag.getArtist() + "<br>" +
                    "专辑：" + tag.getAlbum();
            musicMessage.setText(message);
        } else if (file.hasId3v1Tag()) {
            ID3v1 tag = file.getId3v1Tag();
            message = "<html><body>" +
                    "歌曲名：" + tag.getTitle() + "<br>" +
                    "演唱者：" + tag.getArtist() + "<br>" +
                    "专辑：" + tag.getAlbum();
            musicMessage.setText(message);
        }

    }

}